/**
**********************************************************************
* @file     main.c
* @brief    对文件的简要说明
* @details  对文件的详细说明
* @author   jcai
* @date     2022-04-29 23:13:23
* @copyright Copyright &copy; 2022 wy1107412334@163.com All rights reserved
* @version  v0.0.1
*
* \n Email:  wy1107412334@163.com
* \n Blog:   None
* \n Github: https://github.com/wy1107412334
* \n Gitee:  https://gitee.com/git.git1107412334.com
*
**********************************************************************
* @note
* None.
**********************************************************************
* @attention
* None.
**********************************************************************
@verbatim
@endverbatim
**********************************************************************
* @par 历史记录
* 1. v0.0.1: jcai, 2022-04-29 23:13:23
*   - 首次编写
*
*<center>Copyright &copy; 2022 wy1107412334@163.com All rights reserved</center>
**********************************************************************
*/

/* 头文件导入区 --------------------------------------------------- */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

// 精灵表中的按钮状态
#define  CLIP_MOUSEOVER     0
#define  CLIP_MOUSEOUT      1
#define  CLIP_MOUSEDOWN     2
#define  CLIP_MOUSEUP       3

// 窗口属性
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

// 将要使用的表面
SDL_Surface *buttonSheet = NULL;
SDL_Surface *screen = NULL;

// 事件结构体
SDL_Event event;

// 精灵表的剪辑区域
SDL_Rect clips[4];

// 保存我们定义的按钮范围
SDL_Rect box;
// 指向当前鼠标在我们的按钮内的状态对应的精灵表图
SDL_Rect *clip; // 指向 clips 中的某个元素

SDL_Surface *load_image(const char *file)
{
    SDL_Surface *loadedImage = NULL;
    SDL_Surface *optimizedImage = NULL;

    // 通过 SDL_imag 模块加载图片
    loadedImage = IMG_Load(file);
    if (!loadedImage)   return NULL;

    optimizedImage = SDL_DisplayFormat(loadedImage);
    SDL_FreeSurface(loadedImage);
    if (optimizedImage)
    {
        // 映射关键色
        uint32_t keycolor = SDL_MapRGB(optimizedImage->format, 0, 0xff, 0xff);
        // 将所有颜色为 RGB(0x00, 0xff, 0xff) 的像素设为透明
        SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, keycolor);
    }

    return optimizedImage;
}

void apply_surface(int x, int y, SDL_Surface *src, SDL_Surface *dst, SDL_Rect *clip)
{
    SDL_Rect offset;

    offset.x = x;
    offset.y = y;

    SDL_BlitSurface(src, clip, dst, &offset);
}

int init()
{
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
        return -1;

    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
                              SDL_SWSURFACE);
    if (!screen)    return -2;

    SDL_WM_SetCaption("Button Test", NULL);

#if 0
    // 给窗口背景填充白色
    SDL_FillRect(screen, &screen->clip_rect,
                 SDL_MapRGB(screen->format, 0xff, 0xff, 0xff));
#endif

    return 0;
}

int load_files()
{
    // 加载背景图片
    buttonSheet = load_image("button.png");
    if (!buttonSheet)    return -1;

    return 0;
}

void clean_up()
{
    SDL_FreeSurface(buttonSheet);

    SDL_Quit();
}

void set_clips()
{
    clips[CLIP_MOUSEOVER].x = 0;
    clips[CLIP_MOUSEOVER].y = 0;
    clips[CLIP_MOUSEOVER].w = 320;
    clips[CLIP_MOUSEOVER].h = 240;

    clips[CLIP_MOUSEOUT].x = 320;
    clips[CLIP_MOUSEOUT].y = 0;
    clips[CLIP_MOUSEOUT].w = 320;
    clips[CLIP_MOUSEOUT].h = 240;

    clips[CLIP_MOUSEDOWN].x = 0;
    clips[CLIP_MOUSEDOWN].y = 240;
    clips[CLIP_MOUSEDOWN].w = 320;
    clips[CLIP_MOUSEDOWN].h = 240;

    clips[CLIP_MOUSEUP].x = 320;
    clips[CLIP_MOUSEUP].y = 240;
    clips[CLIP_MOUSEUP].w = 320;
    clips[CLIP_MOUSEUP].h = 240;
}
void button_init(int x, int y, int w, int h)
{
    box.x = x;
    box.y = y;
    box.w = w;
    box.h = h;

    clip = &clips[CLIP_MOUSEOUT];
}
void button_handle_events()
{
    int x = 0, y = 0;

    // 鼠标移动事件
    if (event.type == SDL_MOUSEMOTION)
    {
        x = event.motion.x;
        y = event.motion.y;

        if ((x > box.x) && (x < (box.x + box.w)) &&
            (y > box.y) && (y < (box.y + box.h)))
            clip = &clips[CLIP_MOUSEOVER];
        else
            clip = &clips[CLIP_MOUSEOUT];
    }
    // 鼠标按钮按下事件
    if(event.type == SDL_MOUSEBUTTONDOWN)
    {
        // 鼠标左键按下
        if(event.button.button == SDL_BUTTON_LEFT)
        {
            x = event.button.x;
            y = event.button.y;

            if((x > box.x) && (x < (box.x + box.w)) &&
               (y > box.y) && (y < (box.y + box.h)))
                clip = &clips[ CLIP_MOUSEDOWN ];
        }
    }
    // 鼠标按钮抬起事件
    if(event.type == SDL_MOUSEBUTTONUP)
    {
        // 鼠标左键抬起
        if(event.button.button == SDL_BUTTON_LEFT)
        {
            x = event.button.x;
            y = event.button.y;

            if((x > box.x) && (x < (box.x + box.w)) &&
               (y > box.y) && (y < (box.y + box.h)))
                clip = &clips[ CLIP_MOUSEUP ];
        }
    }
}
void button_show()
{
    apply_surface( box.x, box.y, buttonSheet, screen, clip );
}


/**
**********************************************************************
* @brief    简要说明
* @details  详细说明
* @param    none
* @param[in]     a: 该参数用于输入
* @param[in,out] b: 该参数用于输入和输出
* @param[out]    c: 该参数用于输出
* @retval  none
* @retval  0 函数成功
* @retval  1 函数失败
* @return  返回0成功；否则失败
* @note    none
*/
int main(int argc, char *argv[])
{
    int quit = 0;

    if (init() != 0)
    {
        fprintf(stderr, "SDL初始化失败\n");
        return EXIT_FAILURE;
    }
    if (load_files() != 0)
    {
        fprintf(stderr, "SDL加载 background.png 失败\n");
        return EXIT_FAILURE;
    }

    set_clips();
    button_init(170, 120, 320, 240);

    while (!quit)
    {
        // 处理SDL的事件
        while (SDL_PollEvent(&event))
        {
            button_handle_events();

            // 如果用户点击了窗口右上角的关闭按钮
            if (event.type == SDL_QUIT)
            {
                quit = 1;
                printf("处理退出事件\n");
            }
        }

        SDL_FillRect(screen, &screen->clip_rect,
                     SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));

        button_show();

        // 更新窗口
        if (SDL_Flip(screen) == -1)
        {
            fprintf(stderr, "SDL更新窗口失败\n");
            break;
        }
    }

    clean_up();

    return 0;
}




/***  Copyright (C) 2022 wy1107412334@163.com All rights reserved ***/
/****************************** END OF FILE *************************/

